package com.example.demo61jsonlogin.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;

@Configuration
public class SecurityConfig {

    @Bean
    PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager us = new InMemoryUserDetailsManager();
        us.createUser(User.withUsername("wangnian").password("123").roles("admin").build());
        return us;
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService());
        provider.setPasswordEncoder(passwordEncoder());
        return new ProviderManager(provider);
    }

//    @Bean
    JsonLoginFilter jsonLoginFilter() {
        JsonLoginFilter filter = new JsonLoginFilter();
        filter.setAuthenticationManager(authenticationManager());
        // 登录成功的处理逻辑
        filter.setAuthenticationSuccessHandler((request, response, authentication) -> {
            response.setContentType("application/json;charset=UTF-8");
            User user = (User) authentication.getPrincipal();
            response.getWriter().write(new ObjectMapper().writeValueAsString(user));
        });
        // 登录失败的处理逻辑
        filter.setAuthenticationFailureHandler((request, response, exception) -> {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write("登录失败 " + exception.getMessage());
        });
        // 设置登录成功后，将 SecurityContext 写入到 HttpSession 中 (spring boot 3 之后需要配置，因为 3 之后将 SecurityContextPersistenceFilter 替换为了 SecurityContextHolderFilter)
        filter.setSecurityContextRepository(new HttpSessionSecurityContextRepository());
        return filter;
    }

    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated();

        httpSecurity.csrf().disable();
//                .and().csrf().disable();
        // 添加自定义的 JsonLoginFilter，替换 UsernamePasswordAuthenticationFilter 实现 json 登录
        // 也可以自定义登录接口实现 json 登录
//        httpSecurity.addFilter(jsonLoginFilter());
        return httpSecurity.build();
    }


}
